Laravel Response Headers Setting
简介
上一章,我们了解了响应预处理的原理。
这里做一下总结:
响应预处理:即把我们控制器返回的各式各样的数据类型,统一转换成 Response 类对象,且根据控制器返回的数据,设置 Response 对象的内容体。内容体,即是我们浏览器看到的内容或者前端接收到的 json 字符串。
这一章呢,就是关于 Response 响应头数据设置。
响应头数据的初始化
还记的上一章 Response 构造函数里面有关于 响应头 数据的源码吗,我们来看一下
Symfony\Component\HttpFoundation\Response
public function __construct($content = '', int $status = 200, array $headers = array())
{
// 实例化响应头数据对象
$this->headers = new ResponseHeaderBag($headers);
$this->setContent($content);
$this->setStatusCode($status);
$this->setProtocolVersion('1.0');
}
接下来我们看一下 响应头数据对象 实例化时都做了什么
Symfony\Component\HttpFoundation\ResponseHeaderBag
public function __construct(array $headers = array())
{
// 首先将传进来的 $headers 加进当前响应头数据中,当前没有传 $headers,先不管。
parent::__construct($headers);
// 初始化 Cache-Control 响应头信息
if (!isset($this->headers['cache-control'])) {
$this->set('Cache-Control', '');
}
// 初始化 Date 头信息
if (!isset($this->headers['date'])) {
$this->initDate();
}
}
Cache-Control
通用消息头字段,被用于在 http 请求和响应中,通过指定指令来实现缓存机制。缓存指令是单向的, 这意味着在请求设置的指令,在响应中不一定包含相同的指令。
服务器可以在响应中使用的标准 Cache-Control 指令。
Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-control: max-age=<seconds>
Cache-control: s-maxage=<seconds>
更多详细的说明--->传送门
Date
是一个通用首部,其中包含了报文创建的日期和时间。
语法
Date: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
例如
Date: Wed, 21 Oct 2015 07:28:00 GMT
GMT 是什么
格林尼治标准时间。 在HTTP协议中,时间都是用格林尼治标准时间来表示的,而不是本地时间。
更多详细的说明--->传送门
Respnse Prepare 方法
Prepare 方法:Respnse Headers Setting 正式方法。。。
Symfony\Component\HttpFoundation\Response
public function prepare(Request $request)
{
// 获取上面初始化的 响应头数据对象
$headers = $this->headers;
if ($this->isInformational() || $this->isEmpty()) {
/*
* 如果 HTTP 状态码是 100、101、204、304。。。
* 则内容变成空,移除 Content-Type,Content-Length。
*/
$this->setContent(null);
$headers->remove('Content-Type');
$headers->remove('Content-Length');
} else {
/*
* 根据请求的 _format 获取对应 mimeType,并设置 Content-Type
*/
if (!$headers->has('Content-Type')) {
$format = $request->getRequestFormat();
if (null !== $format && $mimeType = $request->getMimeType($format)) {
$headers->set('Content-Type', $mimeType);
}
}
/*
* 在 Content-Type 后面追加 Charset。。
*/
$charset = $this->charset ?: 'UTF-8';
if (!$headers->has('Content-Type')) {
$headers->set('Content-Type', 'text/html; charset='.$charset);
} elseif (0 === stripos($headers->get('Content-Type'), 'text/') && false === stripos($headers->get('Content-Type'), 'charset')) {
// add the charset
$headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset);
}
/*
* 有我没他,有他没我。(Transfer-Encoding 与 Content-Length 不共戴天)
*/
if ($headers->has('Transfer-Encoding')) {
$headers->remove('Content-Length');
}
/*
* 如果请求 HEAD 方法,移除内容,重新设定 Content-Length
*/
if ($request->isMethod('HEAD')) {
// cf. RFC2616 14.13
$length = $headers->get('Content-Length');
$this->setContent(null);
if ($length) {
$headers->set('Content-Length', $length);
}
}
}
/*
* SERVER_PROTOCOL 不是 1.0 那就是 1.1
*/
if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
$this->setProtocolVersion('1.1');
}
/*
* 1.0 的 HTTP 协议,响应头 Cache-Control:no-cache; 需要 pragma 和 expires。
*/
if ('1.0' == $this->getProtocolVersion() && false !== strpos($this->headers->get('Cache-Control'), 'no-cache')) {
$this->headers->set('pragma', 'no-cache');
$this->headers->set('expires', -1);
}
// 兼容 IE9 一下的响应头协议,谁用 < IE9,就掐死他。
$this->ensureIEOverSSLCompatibility($request);
return $this;
}
这里重点说一下,HTTP 响应码 : 204
204 No Content。
成功状态响应码表示目前请求成功,但客户端不需要更新其现有页面。204 响应默认是可以被缓存的。在响应中需要包含头信息 ETag。
使用惯例是,在 PUT 请求中进行资源更新,但是不需要改变当前展示给用户的页面,那么返回 204 No Content。如果新创建了资源,那么返回 201 Created 。如果页面需要更新以反映更新后的资源,那么需要返回 200 。
这段的原文地址--->传送门
最后
关于 响应头 和 响应码 说一点:
我就是想说:如果想了解其它响应头设置,上面那些传送门的兄弟内容,大家尽管看。。